<?php
declare (strict_types = 1);

namespace app\service\logic\common\user;

use app\model\communal\ExpertTokenModel;
use app\model\communal\UserExpertModel;
use app\service\logic\BaseService;
use app\service\logic\common\order\OrderConsultService;
use thans\jwt\Token;
use think\Collection;
use think\db\exception\DataNotFoundException;
use think\db\exception\DbException;
use think\db\exception\ModelNotFoundException;
use think\Model;

final class ExpertService extends BaseService
{
    protected string $modelClassName = 'UserExpertModel';

    /**
     * 创建
     *
     * @param $params
     * @return UserExpertModel|Model
     */
    public function create($params)
    {
        // region 处理
        $params['province'] = $params['region'][0]['label'];
        $params['province_code'] = $params['region'][0]['value'];
        $params['city'] = $params['region'][1]['label'];
        $params['city_code'] = $params['region'][1]['value'];
        $params['district'] = $params['region'][2]['label'];
        $params['district_code'] = $params['region'][2]['value'];
        unset($params['region']);
        $model = UserExpertModel::create($params);
        return $model;
    }

    /**
     * @param $params
     * @return array|mixed|Model
     * @throws DataNotFoundException
     * @throws ModelNotFoundException
     */
    public function update($params)
    {
        $model = $this->getSimpleDetail($params);
        // region 处理
        $params['province'] = $params['region'][0]['label'];
        $params['province_code'] = $params['region'][0]['value'];
        $params['city'] = $params['region'][1]['label'];
        $params['city_code'] = $params['region'][1]['value'];
        $params['district'] = $params['region'][2]['label'];
        $params['district_code'] = $params['region'][2]['value'];
        unset($params['region']);
        $model->save($params);
        return $model;
    }

    /**
     * 排序参数
     *
     * @param $params
     * @param string $column
     * @param string $type
     * @return array|string[]
     */
    public function orderByParams($params, string $column = 'id', string $type = 'desc')
    {
        if (
            isset($params['app_order']) &&
            in_array(
                $params['app_order'],
                [
                    UserExpertModel::ORDER_OPTION_ONE,
                    UserExpertModel::ORDER_OPTION_TWO,
                    UserExpertModel::ORDER_OPTION_THREE,
                    UserExpertModel::ORDER_OPTION_FOUR,
                    UserExpertModel::ORDER_OPTION_FIVE,
                ]
            )
        ) {
            $orderField = UserExpertModel::$orderRuleMap[$params['app_order']]['orderBy'];
            $orderDir = UserExpertModel::$orderRuleMap[$params['app_order']]['orderDir'];
            $order = [$orderField => $orderDir, 'id' => 'desc'];
            unset($params['order_option']);
        } else {
            $orderField =  isset($params['orderBy']) && !empty($params['orderBy']) ? $params['orderBy'] : $column;
            $orderDir =  isset($params['orderDir']) && !empty($params['orderDir']) ? $params['orderDir'] : $type;
            $order = [$orderField => $orderDir];
        }

        return $order;
    }

    /**
     * 用户token入库
     *
     * @param $id
     * @param $token
     * @return bool
     * @throws DataNotFoundException
     * @throws DbException
     * @throws ModelNotFoundException
     */
    public function insertAccessTokenByID($id, $token)
    {
        $loginsNumber = ExpertTokenModel::where('expert_id', $id)->count();
        $loginLimit = config('logic.user_login_limit');
        if ($loginsNumber >= $loginLimit) {
            // token logout
            $deleteNumber = (int)($loginsNumber - $loginLimit + 1);
            // 仅保留最新
            $deleteList = ExpertTokenModel::field(['expert_id', 'token', 'created_at'])
                ->where('expert_id', $id)
                ->order(['created_at' => 'asc'])
                ->limit($deleteNumber)->select();
            $this->deleteAccessTokenByCollection($deleteList);
        }
        ExpertTokenModel::create([
            'expert_id' => $id,
            'token' => $token,
        ]);
        return true;
    }

    /**
     * 根据Collection删除并禁用管理员Token
     *
     * @param Collection $collection
     * @return bool
     */
    public function deleteAccessTokenByCollection(Collection $collection)
    {
        foreach ($collection as $key=>$model) {
            $token = $model['token'];
            auth('expert')->invalidate($token);
            $model->where('token', $token)->delete();
        }

        return true;
    }

    /**
     * delete cleaning token
     *
     * @param Token $token
     * @return bool
     */
    public function deleteAccessTokenByToken(Token $token)
    {
        $token = (string)$token;
        auth('expert')->invalidate($token);
        return ExpertTokenModel::where('token', $token)->delete();
    }

    /**
     * @param $expertId
     * @return array
     */
    public function getNumberByExpertId($expertId)
    {
        // 结算费用
        $expertAmount = invoke(ExpertStatisticsService::class)->getAmountByExpertId($expertId);
        // 解读订单数量
        $type_1_count = invoke(OrderConsultService::class)->getCount(['expert_id', 'type'], ['expert_id' => $expertId, 'type' => 1]);
        // 咨询订单数量
        $type_2_count = invoke(OrderConsultService::class)->getCount(['expert_id', 'type'], ['expert_id' => $expertId, 'type' => 2]);

        return $expertAmount + [
            'type_1_count' => $type_1_count,
            'type_2_count' => $type_2_count,
        ];
    }
}
